
package com.x52im.rbchat.logic.sns_group.viewmodel;

import android.util.Log;

import com.eva.android.ArrayListObservable;
import com.x52im.rbchat.MyApplication;
import com.x52im.rainbowchat.http.logic.dto.GroupEntity;

import net.x52im.mobileimsdk.android.utils.MBThreadPoolExecutor;

import java.util.List;
import java.util.Observer;
import java.util.concurrent.atomic.AtomicInteger;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

/**
 * 用于新版群聊列表的ViewModel实现类。
 *
 * @author JackJiang
 * @since 8.0
 */
public class GroupsViewModel extends ViewModel {

    private final static String TAG = GroupsViewModel.class.getSimpleName();

    /** 群组列表数据LiveData对象（当本类从IMClientManger的全局群组缓存中载入完成时，通过本对象通知ui更新） */
    private MutableLiveData<List<GroupEntity>> groupsLiveData = null;

    /** 全局群数据模型变动观察者（用于感知IMClientManager的中全局缓存的群列表数据变动） */
    private Observer groupDatasObserver = null;

    /** 这是一个支持多线程原子读的标识量（比布尔量使用更灵活），当载入数据时+1、载入完成时-1，目的是防止重复加载 */
    private final AtomicInteger loadingGroupsCount = new AtomicInteger(0);

    public GroupsViewModel() {
        this.initLiveData();
    }

    /**
     * 本ViewModel类被回收时将要做的处理。
     */
    @Override
    protected void onCleared() {
        super.onCleared();

        Log.i(TAG, "@@@@2【GroupsViewModel】onCleared被调用了！");

        if(this.groupDatasObserver != null) {
            // 从全局群数据模型中清除数据变动观察者
            MyApplication.getInstance2().getIMClientManager().getGroupsProvider()
                    .getGroupsListData(null, false).removeObserver(this.groupDatasObserver);
        }
    }

    /**
     * liveData对象初始化。
     */
    private void initLiveData() {

        Log.i(TAG, "@@@@2【GroupsViewModel】initLiveData被调用了！");

        if (this.groupsLiveData == null) {
            this.groupsLiveData = new MutableLiveData<>();
        }

        // 当加入、创建了新的群聊，或修改了群信息时是通过通知观察者来通知LiveData刷新ui层显示的（保证显示最新群组列表）
        groupDatasObserver = (observable, o) -> {
            Log.i(TAG, "@@@@2【GroupsViewModel】全局数据模型中数据已发生改动，马上通过postValue通知ui层！");
            //何数据变动（可能是信息修改等）更新通知ui刷新显示即可，注意：此时postValue的值为空哦，只是通知，不是需要再传递整个列表数据了
            groupsLiveData.postValue(null);
        };

        // 设置全局群数据模型变动观察者（用于感知IMClientManager的中全局缓存的群列表数据变动）
        MyApplication.getInstance2().getIMClientManager().getGroupsProvider()
                .getGroupsListData(null, false).addObserver(this.groupDatasObserver);

        Log.i(TAG, "@@@@2【GroupsViewModel】initLiveData中..getGroupsListData().addObserver(this.listDatasObserver)！");
    }

    /**
     * 用于关联界面中，首次加载群列表数据模型。
     *
     * 注意：此方法post给ui层的对象是全局群列表数据模型的浅拷贝，后续数据模型的数据改动，经LiveData的通知，只需要
     * 让ui层RecycleView即时调用notifyDataSetChanged()就能刷新最新数据显示，而不需要重复传递整个群列表数据了。
     */
    public void loadGroupsData() {

        Log.i(TAG, "@@@@2【GroupsViewModel】loadGroupsData。。。。");

        // 加载指示标识（用于防止多线程重复加载）
        int count = loadingGroupsCount.get();
        if (count > 0) {
            return;
        }

        // 加载开始时指示标识+1
        loadingGroupsCount.incrementAndGet();

        // 数据处理逻辑在后台进行，提升ui体验
        MBThreadPoolExecutor.runInBackground(() -> {
            long t = System.currentTimeMillis();
            // 加载完成时指示标识-1
            loadingGroupsCount.decrementAndGet();

            // 读取原始群列表数据
            ArrayListObservable<GroupEntity> groupsData = MyApplication.getInstance2().getIMClientManager()
                    .getGroupsProvider().getGroupsListData(null, false);
            List<GroupEntity> groupEntities = groupsData.getDataList();

            // 将数据通知给观察者（以备ui刷新显示）
            if (groupsLiveData != null) {
                groupsLiveData.postValue(groupEntities);
                Log.i(TAG, "@@@@2【GroupsViewModel】loadGroupsData完成，耗时："+(System.currentTimeMillis()-t)+"ms");
            }
        });
    }

    public MutableLiveData<List<GroupEntity>> getGroupsLiveData(){
        return this.groupsLiveData;
    }
}
